//防止重复包含头文件若是没有定义则定义并包含下面的头文件
//若是已经定义了就跳过直到endif
#ifndef __MY_UTIL__
#define __MY_UTIL__
#include<iostream>
#include<fstream>
#include<string>

#include<memory>
#include<sstream>
#include<jsoncpp/json/json.h>

#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
namespace aod{
    //文件属性及操作
    class FileUtil
    {
    private:
        std::string _name;//文件名字
    public:
        FileUtil(const std::string name):_name(name){}
        bool Exists()//判断文件是否存在
        {
            int ret=access(_name.c_str(),F_OK);
            if(ret==0)return true;
            std::cout<<"file is not exists"<<std::endl;
            return false;
        }
        size_t Size()//获取文件大小
        {
            struct stat st;
            int ret=stat(_name.c_str(),&st);
            if(ret==0)return st.st_size;
            std::cout<<"get file size failed"<<std::endl;
            return 0;
        }
        bool GetContent(std::string *body)//获取文件内容到指定空间内
        {
            std::ifstream ifs;//ifstream默认以读方式打开
            ifs.open(_name.c_str(),std::ios::binary);
            if(ifs.is_open()==false)
            {
                std::cout<<"open file failed"<<std::endl;
                return false;
            }
            int len=this->Size();
            body->resize(len);
            ifs.read(&(*body)[0],len);//c_str返回值是一个const char*不能做修改
            
            if(ifs.good()==false)
            {
                std::cout<<"read failed"<<std::endl;
                ifs.close();
                return false;
            }
            // std::cout<<*body<<std::endl;
            ifs.close();
            return true;

        }
        bool ReadContent(const std::string& body)//向文件写入指定内容(body)
        {
            std::ofstream ofs;//写入流
            ofs.open(_name,std::ios::binary);
            if(ofs.is_open()==false)
            {
                std::cout<<"open file failed"<<std::endl;
                return false;
            }

            ofs.write(body.c_str(),body.size());
            if(ofs.good()==false)
            {
                std::cout<<"write failed"<<std::endl;
                ofs.close();
                return false;
            }
            ofs.close();
            // std::cout<<"-----------"<<std::endl;
            return true;
        }
        bool CreateDirectory()//针对目录文件创建目录
        {
            if(this->Exists())
            {
                return true;
            }
            else
            {
                int ret=mkdir(_name.c_str(),0777);
                if(ret==0)return true;
                return false;
            }
        }
    };

    //序列化-反序列化
    class JsonUtil
    {
    private:
    public:
        static bool Serialize(const Json::Value value,std::string *str)//对json格式进行序列化
        {
            Json::StreamWriterBuilder swb;//实例化SWB类对象
            std::unique_ptr<Json::StreamWriter> sw(swb.newStreamWriter());//智能指针进行初始化

            std::stringstream ss;//C++ 流对象用于存放序列化后得数据
            int ret=sw->write(value,&ss);//进行序列化，成功返回0

            if(ret!=0)
            {
                std::cout<<"serialize failed"<<std::endl;
                return false;
            }
            *str=ss.str();//将其赋值给输出参数
            return true;
        }
        static bool UnSerialize(const std::string& str,Json::Value *value)//反序列化变成json格式
        {
            Json::CharReaderBuilder crb;//实例化CRB类对象
            std::unique_ptr<Json::CharReader> cr(crb.newCharReader());//智能指针进行初始化

            std::string err;//存放错误信息
            bool ret=cr->parse(str.c_str(),str.c_str()+str.size(),value,&err);//反序列化
            if(ret==false)
            {
                std::cout<<err<<std::endl;
                return false;
            }
            return true;
        }
    };
}
#endif
